/*
 * busqueda.c
 *
 *  Created on: 21/10/2011
 *      Author: MadeyMaga
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "config.h"
#include "busqueda.h"
#include "Disco.h"
#include "pedidos.h"

extern int	sectors,
			totalSectors,
			algoritmo,
			retardo,
			pistaActual,
			sectorActual,
			discoid;

int 	sentido; // 1: sube 2: baja
int		cylinders,
		heads,
		rpm,
		tSeek,
		tWrite,
		tRead;

int cargarInfoBusqueda()
{
	char posicion[4];

	getConfig("algoplani", &algoritmo);
	getConfig("poscabezal", &posicion);
	getConfig("rpm", &rpm);
	getConfig("cylinders", &cylinders);
	getConfig("sectors", &sectors);
	getConfig("heads", &heads);
	getConfig("timeseek", &tSeek);
	getConfig("timewrite", &tWrite);
	getConfig("timeread", &tRead);
	getConfig("retardo", &retardo);
	getConfig("sentido", &sentido);
	getConfig("discoid", &discoid);

	/* como posicion viene en formato pista:sector lo separamos */
	posicionActual(posicion);

	printf("Info del disco cargada correctamente. \n");

	totalSectors = cylinders * heads * sectors;
	return 0;
}

int timeTrans(int sector, int pista, int tipoTrans)
{
	int				milis = 0;
	int				aux = 0;

	/* es el sector valido?*/
	if(sector > totalSectors)
	{
		printf("Sector %d fuera de rango.\n", sector);
		return 1;
	}

	if(algoritmo)
	{
		/* hay que ir hasta el principio/final del disco?*/
		if((sentido == 1) && (pista < pistaActual))
		{
			/* vamos hasta el final del disco
			 * ("vamos" siempre implica calcular cuanto tardo en llegar hasta un determinado cilindro) */
			milis = (cylinders - pistaActual) * tSeek;
			pistaActual = cylinders - 1;
			sentido = 2;
		}
		else if((sentido == 2) && (pista > pistaActual))
		{
			/* vamos hasta el principio del disco */
			milis = pistaActual * tSeek;
			pistaActual = 0;
			sentido = 1;
		}
	}

	aux = pista - pistaActual;

	/* vamos hasta la pisa necesaria
	 * hago mod porque aux puede ser negativo */
	milis += mod(aux) * tSeek;

	/* esperamos a que se posicione el disco y leemos*/
	milis += retardoRotacional(sectorActual, sector);

	switch(tipoTrans)
	{
		case LEER:
			milis += tRead;
			break;
		case ESCRIBIR:
			milis += tWrite;
			break;
	}

	/* para que NO imprima si el pedido viene de consola por el trace */
	if(tipoTrans != -1)
	{
		printf("Sector transferido: %d:%d.\n", pista, sector);
		printf("Tiempo transcurrido: %d ms.\n", milis);
	}

	pistaActual = pista;
	sectorActual = sector + 1;

	return milis;
}

int getSectorC(int sec)
{
	div_t 	division;
	int		secC; /* cilindro del sector solicitado */

	division = div(sec, heads * sectors);
	secC = division.quot;

	return secC;
}

int getSectorS(int sec)
{
	div_t 	division1, division2;
	int		secS;

	division1 = div(sec, heads * sectors);
	division2 = div(division1.rem, sectors);
	secS = division2.rem;

	return secS;
}

/* "desde" es posicion y "hasta" es a donde voy */
double retardoRotacional(int desde, int hasta)
{
	double 	dif = 0, timePerSec;

	/* por regla de 3 queda que el rps es igual a "rpm / 60000"*/
	timePerSec = (60000 / rpm) / sectors;

	/* diferencia desde donde estoy hasta donde quiero llegar */
	if(hasta > desde)
		dif = hasta - desde;
	else
	/* llego hasta el ultimo sector y despues voy hasta donde quiero ir */
		dif = sectors - desde + hasta;

	return (dif * timePerSec);
}

void posicionActual(char *posicion){

	char *tok;

	tok = strtok(posicion, ":");
	pistaActual = atoi(tok);

	tok = strtok(NULL, "\0");
	sectorActual = atoi(tok);
}
